#include "query.h"


Query::Query(const string &s) :q(new WordQuery(s)) {}

QueryResult NotQuery::eval(const TextQuery &text) const {
	auto result = query.eval(text);

	auto ret_lines = make_shared<set<line_no>>();

	auto beg = result.begin(), end = result.end();

	auto sz = result.get_file()->size();

	for (line_no n = 0; n != sz; ++n) {
		if (beg == end || *beg != n) {
			ret_lines->insert(n);
		} else if (beg != end) {
			++beg;
		}
	}
	
	return QueryResult(rep(), ret_lines, result.get_file());
}

QueryResult AndQuery::eval(const TextQuery &text) const {
	auto right = lhs.eval(text), left = rhs.eval(text);

	auto ret_lines = make_shared<set<line_no>>(left.begin(), left.end());

	set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines->begin()));

	return QueryResult(rep(), ret_lines, left.get_file());
}


QueryResult OrQuery::eval(const TextQuery &text) const {
	auto right = lhs.eval(text), left = rhs.eval(text);

	auto ret_lines = make_shared<set<line_no>>(left.begin(), left.end());

	ret_lines->insert(right.begin(), right.end());

	return QueryResult(rep(), ret_lines, left.get_file());
}


Query QueryHistory::operator[](const size_t p) {
	return querys[p];
}